package calculatrice;
// ==========================================================================
//
//	- Expression -
//
// ==========================================================================
//	<Terme>(<OpeAdd><Terme>)
// ==========================================================================

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import netg.*;
/**
 * <b>La classe Expression </b>
 * <p>
 *	Expression = Terme opeAdd Terme OU Terme
 * </p>
 * @author BOAZIZ M , BOUAYADI R , DRAMSY C , OCCELLO A , SENG D
 * @version v1.0
 *
 * @see Terme
 * @see OpeAdd
 *
 *
 */
public class Expression {
	/**
	 * Le premier Terme de l'expression
	 * @see Expression#setT1(Terme)
	 */
	private Terme t1;
	/**
	 * Le second Terme de l'expression
	 * @see Expression#setT2(Terme)
	 */
	private Terme t2;
	/**
	 * L'Operateur addition de l'expression
	 * @see Expression#setO(char)
	 */
	private OpeAdd O;
	/**
	 * Verifie si l'expression est valide ou pas
	 * @see Expression#isActif()
	 */
	private boolean actif;

	//constructeur
	/**
	 * Constructeur de Expression
	 * <p>
	 * Il créer une expression à partir d'un String S <br/>
	 * <u><b>si ce String a la forme d'une expression :</b></u><br/>
	 * ex: 1 + 2(3*5)/8<br/>
	 * Il mettra actif à true et donc l'expression est valide<br/><br/>
	 * <u><b>si ce String n'a pas  la forme d'une expression :</b></u><br/>
	 * ex: 1++ ou bien a+b<br/>
	 *
	 * Il mettra actif à false et donc l'expression n'est pas valide valide<br/>
	 *
	 * </p>
	 * @param S
	 */
	public Expression(String S)
	{
		t1 = t2 = null;
		O = null;

		// ================
		String regex = "^\\-";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(S);

		if(m.find())
		{
			//detection d'un expression qui commence par un moin
			//On ajoute un zero au debut juste
			S = "0"+S;
		}
		//System.out.println("Expression "+S);
		char C[] = new char [S.length()];
		int i;
		// On remplie les tableaux par la chaine de caracteres
		for(i = 0 ; i < S.length(); i++)
			C[i] = S.charAt(i);
		int couple = 0; // ce sera le couple de parenthses
		boolean find = false;
		int start = 0;int end;

		for(i = 0 ; i < S.length() ; i++)
		{
			if(C[i] == '(') couple ++;
			if(C[i] == ')') couple --;
			else
			{
				if( ( OpeAdd.isOpeAdd(C[i]) ) && couple == 0)
				{
					start = i;
					find = true;
					setO(C[i]);
				}
			}
		}
		//si parenthses non ferme ou non ouverte
		if( couple != 0 )
		{
			actif = false;
			return;
		}
		if(find)
		{
			end = start+1;
			t1 = new Terme(S.substring(0,start));
			t2 = new Terme(S.substring(end ));

			if(!t1.isActif() || !t2.isActif())
			{
				actif = false;
				return;
			}
		}
		else
		{
			t1 = new Terme(S);
			if(!t1.isActif())
			{
				actif = false;
				return;
			}
		}
		actif = true;
	}

	//mutateur
	/**
	 *
	 * <b>Mutateur du Terme t1 : </b><br/>
	 * Cette methode affecte à terme le paramètre t1
	 *
	 * @param t1
	 */
	public void setT1(Terme t1) {
		this.t1 = t1;
	}
	/**
	 *
	 * <b>Mutateur du Terme t2 : </b><br/>
	 * Cette methode affecte à terme le paramètre t2
	 *
	 * @param t2
	 */
	public void setT2(Terme t2) {
		this.t2 = t2;
	}
	/**
	 * <b>Mutateur de O</b><br/>
	 * Initialise O avec le paramètre x
	 * @param x
	 */
	public void setO(char x){
		O = new OpeAdd(x);
	}
	/**
	 * Verifie si l'expression est vrai ou faux
	 * @return boolean actif
	 * @see Terme#isActif()
	 */
	public boolean isActif()
	{
		return actif;
	}

	//Calcul
	/**
	 *
	 * Calcul l'expression en cours grâce au calcul de ses termes
	 * @return Netg
	 * @see Terme#Calcul()
	 */
	public Netg Calcul()
	{
		if( ( t2 == null )||(O == null) )
			return t1.Calcul();
		if( O.isAdd() )
		{
			return NetgMath.addition( t1.Calcul() , t2.Calcul() );
		}
		return NetgMath.soustraction( t1.Calcul() , t2.Calcul() );
	}

}
